//=============================================================================
//
//   Copyright (C) 2020 All rights reserved.
//
//   Filename:		vertex.rs
//
//   Author: Wang Zhecheng - wangzhecheng@yeah.net
//
//   Date: 2020-10-28 04:14
//
//   Last Editors: Wang Zhecheng - wangzhecheng@yeah.net
//
//   Last modified:	2020-11-04 13:01
//
//   Description:
//
//=============================================================================
use crate::component::{dof::Dof, gauss_point::GaussPoint};
use crate::dimension::{DimType, HasDimension};
use crate::geometry::{integratable::Integratable, point::Point, shape::ShapeLike};
use crate::material::{HasMaterial, MaterialLike};
use crate::util::{Hashable, Indexable};
use nalgebra::dimension::Dim;
use std::collections::HashMap;
use std::rc::{Rc, Weak};

impl<DT: DimType> Vertex<DT> {
    pub fn append_dof(&mut self, key: String, dof: Dof) {
        self.dof_list.entry(key).or_insert(dof);
    }
    pub fn get_dof(&self, key: String) -> &Dof {
        self.dof_list
            .get(&key)
            .expect("Failed to get degree of freedom")
    }
    pub fn get_dof_mut(&mut self, key: String) -> &mut Dof {
        self.dof_list
            .get_mut(&key)
            .expect("Failed to get degree of freedom")
    }
}

impl<DT: DimType> Default for Vertex<DT> {
    fn default() -> Self {
        Self {
            id: None,
            pt_list: Vec::new(),
            hash_key: String::new(),
            gp_list: Vec::new(),
            mat: None,
            mesh: [
                HashMap::new(),
                HashMap::new(),
                HashMap::new(),
                HashMap::new(),
            ],
            dof_list: HashMap::new(),
        }
    }
}

// element_like_impl!(Vertex<DT: DimType>);

impl<DT: DimType> HasDimension for Vertex<DT> {
    fn get_dim(&self) -> usize {
        DT::Dim::try_to_usize().expect("Failed to usize dimension")
    }
    fn get_topo_dim(&self) -> usize {
        0 as usize
    }
}

#[test]
fn base() {
    use crate::dimension::PlaneStrain;

    let mut p1 = Point::<nalgebra::U2>::new(1.2f32, 8.2f32);
    p1.set_index(12);
    let sp1 = Rc::new(p1);
    let Vertex = Vertex::<PlaneStrain>::from_plist(vec![Rc::downgrade(&sp1)]);
    println!("{:?}", Vertex);
}
